﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.DisplayManagement.Implementation;
using Orchard.ContentManagement;
using Downplay.Gravity.Services;
using Orchard.DisplayManagement.Shapes;
using Orchard.Utility.Extensions;
using Downplay.Gravity.Models;

namespace Downplay.Gravity.Events
{
    public class GravityShapeEvents : IShapeFactoryEvents
    {
        private IGravityService _gravityService;

        public GravityShapeEvents(IGravityService gravityService)
        {
            _gravityService = gravityService;
        }

        public void Creating(ShapeCreatingContext context)
        {
        }

        public void Created(ShapeCreatedContext context)
        {


            // TODO: I imagine this getting called *lots* especially once we really start messing with the object hierarchy. Following method
            //       needs to be made as quick as possible
            if (!_gravityService.HandlesShape(context.ShapeType)) return;

            // Get shape metadata and perform processing in Display event
            var shapeMetadata = (ShapeMetadata)context.Shape.Metadata;
                shapeMetadata.OnDisplaying(shapeContext =>
                {
                    // TODO: Is this same instance as before?
                    var shapeMetadata2 = (ShapeMetadata)context.Shape.Metadata;
                    // var item = (ContentItem)(context.Shape.ContentItem);
                    var dataContext = new ShapeDataContext()
                    {
                        Shape = context.Shape,
                      //  ContentItem = context.Shape.ContentItem,
                      //  Part = (ContentPart)context.Shape.ContentPart,
                        ShapeType = context.ShapeType,
                        Metadata = shapeMetadata2
                    };

                    // Acquire data values
                    _gravityService.BuildDecorations(dataContext);

                    // TODO: The way this is happening prevents adding arbitrary shapes, locking us into using any of the predefined decoration
                    // types. It also makes it harder to add arbitrary shapes or even supplement the data values from other modules.
                    // Perhaps each decoration can have a string key and we combine the data values rather than treating each decoration as
                    // necessarily separate.
                    foreach (var decoration in dataContext.Decorations) {
                        // Redundant, we just don't need to add the decoration if this is the case?
                        if (decoration.DecorationMode== DataDecorationModes.None) continue;
                        
                        // Make HTML-classified dictionary of data-values
                        var dataAttributes = decoration.Data.ToDictionary(k => ("Data" + k.Key).HtmlClassify(), k => k.Value);

                        switch (decoration.DecorationMode)
                        {
                            case DataDecorationModes.AddAttributesToRender:
                                shapeContext.Shape.Attributes.Merge(dataAttributes);
                                break;
                            case DataDecorationModes.AddDataHandle:
                                var handle = context.New.Handle();
                                handle.Attributes.Merge(dataAttributes);
                                break;
                            case DataDecorationModes.AddDataWrapper:
                                shapeMetadata2.Wrappers.Add("DataWrapper");
                                shapeContext.Shape.DataAttributes = dataAttributes;
                                break;
                        }
                        /* shapeContext.Shape.DataAttributes = dataAttributes;
                        if (dataContext.Data.ContainsKey("Id"))
                        {
                            shapeContext.Shape.DataId = dataContext.Data["Id"];
                        }*/
                    }
                });
        }
    }
}